Request Memoization
https://nextjs.org/docs/app/building-your-application/caching#request-memoization
warning.icon 15 から Data Cache は自動で無効になったが、Request Memoization は無効になっていない
個人的に混同してしまうことが多いので備忘録として radish-miyazaki.icon
Next.js extends the fetch API to automatically memoize requests that have the same URL and options.
https://arc.net/l/quote/nqylmsgt
概要
Next.js の 4 種類のキャッシュ のうちの 1 つで、React Component Tree でデータを再利用することを目的とする
が、React の機能
https://scrapbox.io/files/66cb23f4cca68d001c7dcdff.png
左と中央の図は、1 回のレンダリングで A と B、C の fetch リクエストが複数回発生していることを表している
一番右の図は、Request Memoization が有効ならば必要最小限(3 回)のリクエストだけで済むことを表している
Next.js では Fetch API を拡張し、同じ URL とオプションを持つリクエストを自動的に メモ化 する
Next.js による fetch の拡張
React Component ツリー内の複数箇所で、同じデータに対する fetch 関数を呼び出すことができるが、実行は 1 回だけ行われる
fetch 以外で似たような挙動を実現したい場合、React.cache を用いることができる
注意点
fetch を用いた GET リクエストのみ対応
React Server Component の fetch リクエストが対象
Route Handler の fetch は対象外
React Component Tree に含まれていない、レンダリング外の要素であるため
動作フロー
https://scrapbox.io/files/66cdd360517adc002203d164.png
1. 最初のリクエストはメモリに存在しないので、キャッシュ MISS となる
2. 実際の取得処理または Data Cache を参照し、取得結果をキャッシュに格納する(SET)
3. 以降、発生する一連のレンダリング内の同じリクエストは、キャッシュから結果が取得される(HIT)
4. 一連のレンダリングが完了して Route が完成したタイミングで、キャッシュはリセットされる
サンプルコード
⛔ クエリパラメータが異なるため、メモ化が機能しないケース
code:tsx
export async function generateMetadata({ params }: Props): Promise<Metadata> {
// ...
const res = await fetch(
http://localhost:8082/api/categories/${categoryName}?page=1&take=10,
{
cache: "no-store",
}
);
// ...
}
export default async function Page({ params, searchParams }: Props) {
// ...
const res = await fetch(
// クエリパラメータが generateMetadata と異なる
http://localhost:8082/categories/${categoryName}?page=${page}&take=15,
{
cache: "no-store"
}
);
// ...
})
ここでは cache: "no-store" を意図的に使用し、Data Cache が行われないようにしている
✅ 回避策
クエリパラメータ take が同じ値になるように修正する
code:tsx
export async function generateMetadata({ params }: Props): Promise<Metadata> {
// ...
const res = await fetch(
http://localhost:8082/api/categories/${categoryName}?page=1&take=15,
{
cache: "no-store",
}
);
// ...
}
#Next.js